Classes and objects created in the ScriptX language using the syntax in this chapter are fully-featured, first-class objects. This means that the ScriptX language, the parser, and the compiler treat user-defined classes and objects in the same way as built-in system classes and objects. This allows you to easily build powerful specialized extensions to ScriptX on top of the core ScriptX implementation.
This chapter describes the syntax for developing new singly- and multiply-inherited classes and objects, and for defining methods and variables within them. It also describes some methods that are commonly overridden in subclasses so that those classes can interact effectively with the language and with other classes in the ScriptX core classes library.
class
expression.
class variableName ( classList )The
[ class variables
. . . ]
[ instance variables
. . . ]
[ class methods
. . . ]
[ instance methods
. . . ]
end
class
expression has an introductory clause
followed by four main sections for defining the features of
the new class: class variables
, class
methods
, instance variables
, and
instance methods.
Each part of the expression is
described in the following sections.
You must specify the sections of the class
expression in the order in which they appear above, although
you do not need to include all of them. Use only the sections
you need in order to create your specialized subclass. Each
section can be on a separate line, as shown in the syntax, or
all can be on the same line, or the two styles can be used in
any combination.
class
expression
specifies the name of the new class and the inheritance of
this class. class variableName ( classList )lThe variableName part of this line specifies the name of the variable to which this class object will be assigned once it has been created. Like all variables in ScriptX, if the variable named by variableName has not been previously declared, it is automatically declared global. You can specify that the variable name is to be declared locally by putting the reserved word
. . .
end
local
in front of the reserved word
class
. Note that just as with local variables,
you can only define a local class inside a local scope (that
is, not at the top level).(
local class SortedLinkedList (LinkedList)
end
)
This example creates a subclass of the class
LinkedList
(with no further specialization) and
assigns it to the local variable
SortedLinkedList
.
In addition, the variable to which a class is assigned is
declared constant
, which means that you cannot
assign anything else to it once the class has been created.
This is to prevent accidentally overwriting the definition of
a class with a simple assignment. You can, however, redefine a
class using the name of the original class. (Some restrictions
apply; see "A Note on Redefining
Classes" on page 113 for more information.)
class variableName ( classList )The classList, within parentheses, specifies a list of classes from which this class inherits (that this class is a subclass of). The classList can be a single class, or a list of classes separated by commas. If you specify multiple classes in classList, your new class multiply inherits from all those classes. See "Multiple Inheritance" on page 122 for more information on classes with multiple superclasses.
. . .
end
class
expression with the same name as a previously-defined class.
There are several things to note about redefining classes:class
expression to
define a class, all previous definitions of that class are
replaced. You cannot incrementally add to the definition of a
class using multiple class
definitions.
undefined
), or removing instances
from other structures such as collections. Once all references
to an instance are gone, the ScriptX garbage collector removes
that instance.
Instance variables are variables whose values can vary from
instance to instance. For example, the class Car
may define an instance variable called color
.
Each instance of Car
can then have its own value
for color
.
Class variables are variables that relate to the class itself,
and are accessible to and shared by all the instances of a
class, including the class itself. For example, the class
LuxuryCar
might have a features
class variable that holds an array of features common to all
instances of luxury cars, such as @antiLockBrakes
or @woodPaneling
. Those features are shared by
all instances of LuxuryCar
, and if the value of
that variable is ever changed, it affects all those instances
equally.
Both class and instance variables are accessed through the use of special generic functions called setters and getters. Setters change (or set) the value of a variable; getters query for (or get) the current value of a variable. ScriptX language constructs for querying and changing class and instance variables are described beginning on page 61. Use these generic functions to indirectly gain access to the variable itself.
ScriptX provides several mechanisms for defining class and instance variables with many different features, including read-only variables, variables that automatically calculate their values when they are queried by some other method in the class or object, or variables that discard their values when stored on disk. Each of these more complex forms for defining variables, as well as details on setter and getter generic functions, is described in detail in "Defining Class and Instance Variables" on page 140.
class variableName ( classList )The reserved words
class variables
varName
varName:initialValue
. . .
instance variables
varName
varName:initialValue
. . .
end
class variables
can be
shortened to class vars
. Similarly, the reserved
words instance variables
can the shortened to
inst variables
or simply inst vars
.
Each short form is equivalent to its longer counterpart. After
these reserved words, you can specify any number of variable
names (here, varName) on separate lines, or all on
one line separated by commas, or in any combination.
You can also specify initial values for those variables
(initialValue) by supplying a colon and the value
after the variable. The initial value of a class variable is
assigned when the class is created; the initial value for an
instance variable is assigned each time a new instance of that
class is created. If you do not specify initial values for a
class or instance variable, its value is
undefined
.
Each of these forms creates "real" instance variables, that is, variables that exist as slots in memory. They also construct pairs of setter and getter functions automatically for each of the variables listed when the class is created. For more details on the setter and getter functions, see "Defining Class and Instance Variables" on page 140.
The following example shows the definition and use of a class variable:
class PurpleDragon ()
class vars numDragons : 0
instance methods
method moreDragons self -> (
(getClass self).numDragons := (getClass self).numDragons + 1
)
end
This example defines a class PurpleDragon
. Since
no class is specified in the class inheritance list, the class
inherits directly from RootObject
, the root
system class. The PurpleDragon
class defines a
class variable, numDragons
, which is initially
set to 0
. It also defines an instance method to
increase the value of the class variable
numDragons
by one. Instance methods are described
in the section "Class and Instance
Methods" on page 116.
dragon1 := new PurpleDragon
dragon2 := new PurpleDragon
PurpleDragon.numDragons -- the initial value
0
moreDragons dragon1
1
moreDragons dragon2
2
PurpleDragon.numDragons -- find out new value
2 i
For example, suppose you have a class LuxuryCar
,
which defines a class variable paneling
, whose
default value is @oak
.
class LuxuryCar ()
class variables paneling:@oak
endNow, suppose you created a subclass of
LuxuryCar
called BargainLuxuryCar
. The
BargainLuxuryCar
class inherits the
paneling
class variable (and its value) from
LuxuryCar
: class BargainLuxuryCar (LuxuryCar) end
BargainLuxuryCar.paneling
However, because each class owns its own slot for class variables, even inherited ones, if you change the value of@oak
LuxuryCar
's class variable paneling
,
BargainLuxuryCar
's version of the class variable
paneling
is not affected.LuxuryCar.paneling := @teak
@teak
BargainLuxuryCar.paneling
@oak
class methods
or instance
methods
sections of the class expression:class variableName ( classList )The reserved words
class methods
methodDefinition
. . .
instance methods
methodDefinition
. . .
end
instance methods
can be
shortened to inst methods
; both forms are
equivalent.
Both the class methods
and instance
methods
reserved words are followed by any number of
individual method definitions. Method definitions are very
similar to function definitions-see "Defining Methods" on page 125 for
more information.
One of the most commonly defined instance methods is the
init
method, which determines how an instance of
a class is to be initialized when the new
method
is called on the class. For detailed information on defining
initialization methods, see the discussion of the
new
, init
, and
afterInit
methods that begins on page 132.
This document is part of the ScriptX Language Guide, one of the volumes of the ScriptX Technical Reference Series. ScriptX is developed by the ScriptX Engineering Team at Apple Computer, successor to the Kaleida Engineering Team at Kaleida Labs, Inc.